
#ifndef _WWWINDOWS_10_
#define _WWWINDOWS_10_
#include "windows.h"
#include <string>
#include <exception>

namespace ww
{
	class WindowsNotInitializedException : public std::exception
	{

	public:
		std::string what()
		{
			std::string exMessage("La instancea de la clase Windows no se ha inicializado.");
			return exMessage;
		}
	};
	class Windows : std::string
	{
		typedef LRESULT (CALLBACK *pWndProc)(HWND, UINT, WPARAM, LPARAM);

	private: 
		HWND m_wHandle;
		WNDCLASS m_wClass;
		HINSTANCE m_hInstance;
		BOOL m_initialized;
		int m_show;

		//Conversion function to wstring
		std::wstring s2ws(const std::string& s)
		{
			int len;
			int slength = (int)s.length() + 1;
			len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
			wchar_t* buf = new wchar_t[len];
			MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
			std::wstring r(buf);
			delete[] buf;
			return r;
		}

	public:
		//Constructors
		Windows(pWndProc pWP, HINSTANCE hI, const char* tittle, int show) : m_wHandle(nullptr), m_hInstance(hI), std::string(tittle),
			m_show(show), m_initialized(false)
		{
			m_wClass.style         = CS_HREDRAW | CS_VREDRAW;
			m_wClass.lpfnWndProc   = pWP;
			m_wClass.cbClsExtra    = 0;
			m_wClass.cbWndExtra    = 0;
			m_wClass.hInstance     = hI;
			m_wClass.hIcon         = LoadIcon(0, IDI_APPLICATION);
			m_wClass.hCursor       = LoadCursor(0, IDC_ARROW);
			m_wClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
			m_wClass.lpszMenuName  = 0;
			m_wClass.lpszClassName = L"BasicWndClass";
		}
		Windows(WNDCLASS* wc, HINSTANCE hI, int show) : m_wHandle(nullptr), m_wClass(*wc), m_hInstance(hI), m_show(show),
			m_initialized(false){}
		
		//Interface.
		BOOL InitializeNormalWindows() 
		{
			if(!RegisterClass(&m_wClass))
				return false;

			m_wHandle = CreateWindow(
				L"BasicWndClass",     // Registered WNDCLASS instance to use.
				s2ws(*this).c_str(),  // window title,
				WS_OVERLAPPEDWINDOW,  // style flags
				CW_USEDEFAULT,        // x-coordinate
				CW_USEDEFAULT,        // y-coordinate
				CW_USEDEFAULT,        // width
				CW_USEDEFAULT,        // height
				0,                    // parent window
				0,                    // menu handle
				m_hInstance,          // app instance
				0);                   // extra creation parameters

			if(m_wHandle == 0)
				return false;

			ShowWindow(m_wHandle, m_show);
			UpdateWindow(m_wHandle);

			m_initialized = true;

			return true;
		}

		int Run()
		{
			if(!m_initialized)
			{
				WindowsNotInitializedException ex;
				MessageBox(0, s2ws(ex.what()).c_str(), L"Error", MB_OK);
				throw ex;
			}
			MSG msg = {0};

			BOOL bRet = 1;
			while( (bRet = GetMessage(&msg, 0, 0, 0)) != 0 )
			{
				if(bRet == -1)
				{
					MessageBox(0, L"GetMessage FAILED", L"Error", MB_OK);
					break;
				}
				else
				{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
				}
			}
			return (int)msg.wParam;
		}

		HWND getHWND() { return m_wHandle; }

		//Override default member functions/overload of operators.
		HWND operator&() { return m_wHandle; }
	};
};
#endif